package priv.conceit.study.basic.proxy.dynamic;

import lombok.*;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * study
 *
 * @author Conceit
 * 2019/12/2 增加方法
 * @since 1.0.0, 2019/12/2
 */
@Slf4j
@RequiredArgsConstructor
public class StarProxy<T extends Star> implements InvocationHandler{

	/**
	 * 目标类，也就是被代理对象
	 */
	@Getter
	@Setter
	@NonNull
	private T target;

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		log.info("开始进入 InvocationHandler,star proxy before");
		Object result=method.invoke(target,args);
		log.info("开始进入 InvocationHandler,star proxy after");
		return result;
	}

	/**
	  * @description: buildProxyObj 实际 生成代理对象
	  * 前两个参数的意思是在同一个classloader下通过接口创建出一个对象，该对象需要一个属性，也就是第三个参数，它是一个InvocationHandler
	  * ClassLoader loader
	  * Class<?>[] interfaces
	  * InvocationHandler h
	  * 只有声明了<T>的方法才是泛型方法，泛型类中的使用了泛型的成员方法并不是泛型方法。
	  * @return: java.lang.Object
	  * @author: conceit
	  * @date: 2019/12/2 16:07
	  */
	public <T extends Star> T  buildProxyObj(){
		return  (T)Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this::invoke);
	}

}
